﻿using FreeSql;
using System.Threading.Tasks;

namespace FreesqlSimpleExtension.Test
{
    [TestClass]
    public sealed class Test1
    {
        IFreeSql freeSql;

        public Test1()
        {
            freeSql = new FreeSqlBuilder()
                .UseConnectionString(DataType.Sqlite, @"Data Source=test.db")
                .UseAutoSyncStructure(true)
                .Build();

            if (freeSql.Select<TestEntity>().Count() <= 0)
            {
                freeSql.Insert(new List<TestEntity>()
                {
                    new(){ Name="张三",Age=18,CreateTime = new DateTime(2025,1,1,1,2,3) },
                    new(){ Name="李四",Age=26,CreateTime = new DateTime(2025,1,2)  },
                    new(){ Name="王五",Age=30,CreateTime = new DateTime(2025,1,3)  },
                    new(){ Name="",Age=null,CreateTime = new DateTime(2025,1,3)  },
                    new(){ Age=66,CreateTime = new DateTime(2025,1,3)  }
                }).ExecuteAffrows();
            }
        }

        [TestMethod]
        public async Task Test_Name_Contains()
        {
            var query = new TestQueryInput { Name = "三" };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).FirstAsync();
            Assert.AreEqual("张三", result.Name);
        }

        [TestMethod]
        public async Task Test_Name_ArrayContains()
        {
            var query = new TestQueryInput { NameArray = ["张三", "李四"] };
            var select = freeSql.Select<TestEntity>();
            var sql = select.QueryEntity(query).ToSql();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.IsTrue(result.Any(a => a.Name == "张三"));
            Assert.IsTrue(result.Any(a => a.Name == "李四"));
        }

        [TestMethod]
        public async Task Test_Age_Gte()
        {
            var query = new TestQueryInput { AgeGte = 26 };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.IsTrue(result.All(a => a.Age >= 26));
        }

        [TestMethod]
        public async Task Test_Age_Lte()
        {
            var query = new TestQueryInput { AgeLte = 26 };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.IsTrue(result.All(a => a.Age <= 26));
        }

        [TestMethod]
        public async Task Test_Age_Between()
        {
            var query = new TestQueryInput { AgeLte = 18, AgeGte = 26 };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.IsTrue(result.All(a => a.Age >= 18 && a.Age <= 26));
        }

        [TestMethod]
        public async Task Test_DateEq()
        {
            var query = new TestQueryInput { CreateTime = new DateTime(2025, 1, 2) };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).FirstAsync();
            Assert.AreEqual(new DateTime(2025, 1, 2), result.CreateTime.Date);
        }

        [TestMethod]
        public async Task Test_OrderBy()
        {
            var query = new TestQueryInput { OrderBy = ["Age desc"] };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.AreEqual(30, result.First().Age);
        }

        [TestMethod]
        public async Task Test_EmptyQuery()
        {
            var query = new TestQueryInput();
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.AreEqual(3, result.Count);
        }


        [TestMethod]
        public async Task Test_Range()
        {
            var query = new TestQueryInput() { TimeRange = [new DateTime(2025, 1, 1,1,2,3), new DateTime(2025, 1, 2)] };
            var select = freeSql.Select<TestEntity>();
            var sql = select.QueryEntity(query).ToSql();
            var result = await select.QueryEntity(query).ToListAsync();

            Assert.AreEqual(2, result.Count);
        }


        [TestMethod]
        public async Task Test_Null()
        {
            var query = new TestQueryInput() { NameNull="1" };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.AreEqual(2, result.Count);
        }

        [TestMethod]
        public async Task Test_NotNull()
        {
            var query = new TestQueryInput() { AgeNotNull = "1" };
            var select = freeSql.Select<TestEntity>();
            var result = await select.QueryEntity(query).ToListAsync();
            Assert.AreEqual(4, result.Count);
        }
    }
}
